Fix up visibility so that focus, cursor_visible and blink interact
authorOwen Taylor <otaylor@redhat.com>
Fri, 8 Sep 2000 18:33:03 +0000 (18:33 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Fri, 8 Sep 2000 18:33:03 +0000 (18:33 +0000)
Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>

* gtk/gtktextview.c: Fix up visibility so that focus,
cursor_visible and blink interact properly.  Reenable cursor blink
which had been roughly disabled. Make blink and focus
properly per-view.

* gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
Add a flag for whether to display insertion cursor and
a function to set the flag.

* gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
get_line_y() to get_line_yrange(), to be a bit more generally
useful.

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtktextlayout.c
gtk/gtktextlayout.h
gtk/gtktextview.c

index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 1c1b8431680af5e882d1ee5a405bafa8b8736517..39af9097c48138281bc81017d851bdf73df3fca3 100644 (file)
@@ -1,3 +1,18 @@
+Fri Sep  8 14:28:00 2000  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtktextview.c: Fix up visibility so that focus,
+       cursor_visible and blink interact properly.  Reenable cursor blink
+       which had been roughly disabled. Make blink and focus
+       properly per-view.
+
+       * gtk/gtktextlayout.[ch] (gtk_text_layout_set_cursor_visible):
+       Add a flag for whether to display insertion cursor and
+       a function to set the flag.
+
+       * gtk/gtktextlayout.c (gtk_text_layout_get_line_yrange): Change
+       get_line_y() to get_line_yrange(), to be a bit more generally
+       useful.
+
 Thu Sep 07 20:54:33 2000  George Lebl <jirka@5z.com>
 
        * gtk/gtkmenu.c:  in gtk_menu_set_submenu_navigation_region
index 09a0ff2a13f37d524cb4d590fc3f653fa94033b8..a169fe486bda74aa1a275b5a000e51494ed46332 100644 (file)
@@ -75,6 +75,8 @@ static void gtk_text_layout_invalidated     (GtkTextLayout     *layout);
 static void gtk_text_layout_real_invalidate     (GtkTextLayout     *layout,
                                                 const GtkTextIter *start,
                                                 const GtkTextIter *end);
+static void gtk_text_layout_invalidate_cache    (GtkTextLayout     *layout,
+                                                GtkTextLine       *line);
 static void gtk_text_layout_real_free_line_data (GtkTextLayout     *layout,
                                                 GtkTextLine       *line,
                                                 GtkTextLineData   *line_data);
@@ -177,6 +179,7 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
 void
 gtk_text_layout_init (GtkTextLayout *text_layout)
 {
+  text_layout->cursor_visible = TRUE;
 }
 
 GtkTextLayout*
@@ -329,6 +332,56 @@ gtk_text_layout_set_screen_width (GtkTextLayout *layout, gint width)
   gtk_text_layout_invalidate_all (layout);
 }
 
+/**
+ * gtk_text_layout_set_cursor_visible:
+ * @layout: a #GtkTextLayout
+ * @cursor_visible: If %FALSE, then the insertion cursor will not
+ *   be shown, even if the text is editable. 
+ * 
+ * Sets whether the insertion cursor should be shown. Generally,
+ * widgets using #GtkTextLayout will hide the cursor when the
+ * widget does not have the input focus.
+ **/
+void
+gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
+                                   gboolean       cursor_visible)
+{
+  cursor_visible = (cursor_visible != FALSE);
+
+  if (layout->cursor_visible != cursor_visible)
+    {
+      GtkTextIter iter;
+      gint y, height;
+      
+      layout->cursor_visible = cursor_visible;
+
+      /* Now queue a redraw on the paragraph containing the cursor
+       */
+      gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter,
+                                       gtk_text_buffer_get_mark (layout->buffer, "insert"));
+
+      gtk_text_layout_get_line_yrange (layout, &iter, &y, &height);
+      gtk_text_layout_changed (layout, y, height, height);
+
+      gtk_text_layout_invalidate_cache (layout, gtk_text_iter_get_text_line (&iter));
+    }
+}
+
+/**
+ * gtk_text_layout_get_cursor_visible:
+ * @layout: a #GtkTextLayout
+ * 
+ * Returns whether the insertion cursor will be shown.
+ * 
+ * Return value: if %FALSE, the insertion cursor will not be
+    shown, even if the text is editable.
+ **/
+gboolean
+gtk_text_layout_get_cursor_visible (GtkTextLayout *layout)
+{
+  return layout->cursor_visible;
+}
+
 void
 gtk_text_layout_get_size (GtkTextLayout *layout,
                           gint *width,
@@ -517,9 +570,18 @@ gtk_text_layout_invalidate_all (GtkTextLayout *layout)
   gtk_text_layout_invalidate (layout, &start, &end);
 }
 
-/* FIXME: This is now completely generic, and we could probably be
- * moved into gtktextbtree.c.
- */
+static void
+gtk_text_layout_invalidate_cache (GtkTextLayout *layout,
+                                 GtkTextLine   *line)
+{
+  if (layout->one_display_cache && line == layout->one_display_cache->line)
+    {
+      GtkTextLineDisplay *tmp_display = layout->one_display_cache;
+      layout->one_display_cache = NULL;
+      gtk_text_layout_free_line_display (layout, tmp_display);
+    }
+}
+
 static void
 gtk_text_layout_real_invalidate (GtkTextLayout *layout,
                                  const GtkTextIter *start,
@@ -546,13 +608,7 @@ gtk_text_layout_real_invalidate (GtkTextLayout *layout,
       if (line_data &&
          (line != last_line || !gtk_text_iter_starts_line (end)))
        {
-         if (layout->one_display_cache &&
-             line == layout->one_display_cache->line)
-           {
-             GtkTextLineDisplay *tmp_display = layout->one_display_cache;
-             layout->one_display_cache = NULL;
-             gtk_text_layout_free_line_display (layout, tmp_display);
-           }
+         gtk_text_layout_invalidate_cache (layout, line);
          gtk_text_line_invalidate_wrap (line, line_data);
        }
       
@@ -1148,11 +1204,12 @@ add_cursor (GtkTextLayout      *layout,
   PangoRectangle strong_pos, weak_pos;
   GtkTextCursorDisplay *cursor;
 
-  /* Hide insertion cursor when we have a selection
+  /* Hide insertion cursor when we have a selection or the layout
+   * user has hidden the cursor.
    */
   if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
                                      (GtkTextMark*)seg) &&
-      gtk_text_buffer_get_selection_bounds (layout->buffer, &selection_start, &selection_end))
+      (!layout->cursor_visible || gtk_text_buffer_get_selection_bounds (layout->buffer, &selection_start, &selection_end)))
     return;
   
   pango_layout_get_cursor_pos (display->layout, start, &strong_pos, &weak_pos);
@@ -1589,27 +1646,41 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout  *layout,
 }
 
 /**
- * gtk_text_layout_get_line_y:
+ * gtk_text_layout_get_line_yrange:
  * @layout: a #GtkTextLayout
  * @iter:   a #GtkTextIter
+ * @y:      location to store the top of the paragraph in pixels,
+ *          or %NULL.
+ * @height  location to store the height of the paragraph in pixels,
+ *          or %NULL.
  * 
- * Find the y coordinate of the top of the paragraph containing
+ * Find the range of y coordinates for the paragraph containing
  * the given iter.
- * 
- * Return value: the y coordinate, in pixels.
  **/
-gint
-gtk_text_layout_get_line_y (GtkTextLayout     *layout,
-                           const GtkTextIter *iter)
+void
+gtk_text_layout_get_line_yrange (GtkTextLayout     *layout,
+                                const GtkTextIter *iter,
+                                gint              *y,
+                                gint              *height)
 {
   GtkTextLine *line;
   
-  g_return_val_if_fail (GTK_IS_TEXT_LAYOUT (layout), 0);
-  g_return_val_if_fail (gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer), 0);
+  g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
+  g_return_if_fail (gtk_text_iter_get_btree (iter) == _gtk_text_buffer_get_btree (layout->buffer));
   
   line = gtk_text_iter_get_text_line (iter);
-  return gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
+
+  if (y)
+    *y = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
                                        line, layout);
+  if (height)
+    {
+      GtkTextLineData *line_data = gtk_text_line_get_data (line, layout);
+      if (line_data)
+       *height = line_data->height;
+      else
+       *height = 0;
+    }
 }
 
 void
index 79871d389020610d6fdc5244a87c660a165a50f4..048b55d7716977d79bda2fb3cdfa53349b71b361 100644 (file)
@@ -67,6 +67,9 @@ struct _GtkTextLayout
   
   /* Whether we are allowed to wrap right now */
   gint wrap_loop_count;
+
+  /* Whether to show the insertion cursor */
+  guint cursor_visible : 1;
 };
 
 struct _GtkTextLayoutClass
@@ -143,16 +146,20 @@ extern PangoAttrType gtk_text_attr_appearance_type;
 GtkType        gtk_text_layout_get_type (void) G_GNUC_CONST;
 GtkTextLayout *gtk_text_layout_new      (void);
 
-void gtk_text_layout_set_buffer            (GtkTextLayout      *layout,
-                                           GtkTextBuffer      *buffer);
-void gtk_text_layout_set_default_style     (GtkTextLayout      *layout,
-                                           GtkTextAttributes  *values);
-void gtk_text_layout_set_contexts          (GtkTextLayout      *layout,
-                                           PangoContext       *ltr_context,
-                                           PangoContext       *rtl_context);
-void gtk_text_layout_default_style_changed (GtkTextLayout      *layout);
-void gtk_text_layout_set_screen_width      (GtkTextLayout      *layout,
-                                           gint                width);
+void gtk_text_layout_set_buffer             (GtkTextLayout     *layout,
+                                            GtkTextBuffer     *buffer);
+void gtk_text_layout_set_default_style      (GtkTextLayout     *layout,
+                                            GtkTextAttributes *values);
+void gtk_text_layout_set_contexts           (GtkTextLayout     *layout,
+                                            PangoContext      *ltr_context,
+                                            PangoContext      *rtl_context);
+void gtk_text_layout_default_style_changed  (GtkTextLayout     *layout);
+void gtk_text_layout_set_screen_width       (GtkTextLayout     *layout,
+                                            gint               width);
+
+void     gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
+                                            gboolean       cursor_visible);
+gboolean gtk_text_layout_get_cursor_visible (GtkTextLayout *layout);
 
 /* Getting the size or the lines potentially results in a call to
  * recompute, which is pretty massively expensive. Thus it should
@@ -225,8 +232,10 @@ void     gtk_text_layout_changed              (GtkTextLayout     *layout,
 void     gtk_text_layout_get_iter_location    (GtkTextLayout     *layout,
                                               const GtkTextIter *iter,
                                               GdkRectangle      *rect);
-gint     gtk_text_layout_get_line_y           (GtkTextLayout     *layout,
-                                              const GtkTextIter *iter);
+void     gtk_text_layout_get_line_yrange      (GtkTextLayout     *layout,
+                                              const GtkTextIter *iter,
+                                              gint              *y,
+                                              gint              *height);
 void     gtk_text_layout_get_cursor_locations (GtkTextLayout     *layout,
                                               GtkTextIter       *iter,
                                               GdkRectangle      *strong_pos,
index 857e7578c4eb9605015b70a8563d4b1cd3938aa4..e97df15f7211f820c8c4087129f0b88f872e6ea5 100644 (file)
@@ -986,18 +986,24 @@ gtk_text_view_set_cursor_visible    (GtkTextView   *text_view,
 {
   g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
 
+  setting = (setting != FALSE);
+
   if (text_view->cursor_visible != setting)
     {
       text_view->cursor_visible = setting;
 
       if (GTK_WIDGET_HAS_FOCUS (text_view))
-        {
-          GtkTextMark *insert;
-  
-          insert = gtk_text_buffer_get_mark (text_view->buffer,
-                                             "insert");
-          gtk_text_mark_set_visible (insert, text_view->cursor_visible);
-        }
+       {
+         if (text_view->layout)
+           {
+             gtk_text_layout_set_cursor_visible (text_view->layout, setting);
+         
+             if (setting)
+               gtk_text_view_start_cursor_blink (text_view);
+             else
+               gtk_text_view_stop_cursor_blink (text_view);
+           }
+       }
     }
 }
 
@@ -1039,7 +1045,7 @@ gtk_text_view_destroy (GtkObject *object)
 
   gtk_text_view_destroy_layout (text_view);
   gtk_text_view_set_buffer (text_view, NULL);
-  
+
   (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
@@ -1177,7 +1183,9 @@ gtk_text_view_size_allocate (GtkWidget *widget,
    * the buffer 
   */
   gtk_text_view_get_first_para_iter (text_view, &first_para);
-  y = gtk_text_layout_get_line_y (text_view->layout, &first_para) + text_view->first_para_pixels;
+  gtk_text_layout_get_line_yrange (text_view->layout, &first_para, &y, NULL);
+
+  y += text_view->first_para_pixels;
 
   /* Ensure h/v adj exist */
   get_hadjustment (text_view);
@@ -1693,15 +1701,15 @@ gtk_text_view_button_release_event (GtkWidget *widget, GdkEventButton *event)
 static gint
 gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
 {
-  GtkTextMark *insert;
+  GtkTextView *text_view = GTK_TEXT_VIEW (widget);
   
   GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
 
-  insert = gtk_text_buffer_get_mark (GTK_TEXT_VIEW (widget)->buffer,
-                                     "insert");
-  gtk_text_mark_set_visible (insert, GTK_TEXT_VIEW (widget)->cursor_visible);
-
-  gtk_text_view_start_cursor_blink (GTK_TEXT_VIEW (widget));
+  if (text_view->cursor_visible && text_view->layout)
+    {
+      gtk_text_layout_set_cursor_visible (text_view->layout, TRUE);
+      gtk_text_view_start_cursor_blink (text_view);
+    }
 
   gtk_im_context_focus_in (GTK_TEXT_VIEW (widget)->im_context);
   
@@ -1711,15 +1719,15 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
 static gint
 gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
 {
-  GtkTextMark *insert;
+  GtkTextView *text_view = GTK_TEXT_VIEW (widget);
   
   GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
 
-  insert = gtk_text_buffer_get_mark (GTK_TEXT_VIEW (widget)->buffer,
-                                     "insert");
-  gtk_text_mark_set_visible (insert, FALSE);
-
-  gtk_text_view_stop_cursor_blink (GTK_TEXT_VIEW (widget));
+  if (text_view->cursor_visible && text_view->layout)
+    {
+      gtk_text_layout_set_cursor_visible (text_view->layout, FALSE);
+      gtk_text_view_stop_cursor_blink (text_view);
+    }
 
   gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context);
   
@@ -1783,33 +1791,19 @@ static gint
 blink_cb (gpointer data)
 {
   GtkTextView *text_view;
-  GtkTextMark *insert;
   
   text_view = GTK_TEXT_VIEW (data);
 
-  insert = gtk_text_buffer_get_mark (text_view->buffer,
-                                     "insert");
-  
-  if (!GTK_WIDGET_HAS_FOCUS (text_view))
-    {
-      /* paranoia, in case the user somehow mangles our
-         focus_in/focus_out pairing. */
-      gtk_text_mark_set_visible (insert, FALSE);
-      text_view->blink_timeout = 0;
-      return FALSE;
-    }
-  else
-    {
-      gtk_text_mark_set_visible (insert,
-                                 !gtk_text_mark_is_visible (insert));
-      return TRUE;
-    }
+  g_assert (text_view->layout && GTK_WIDGET_HAS_FOCUS (text_view) && text_view->cursor_visible);
+
+  gtk_text_layout_set_cursor_visible (text_view->layout,
+                                     !gtk_text_layout_get_cursor_visible (text_view->layout));
+  return TRUE;
 }
 
 static void
 gtk_text_view_start_cursor_blink (GtkTextView *text_view)
 {
-  return;
   if (text_view->blink_timeout != 0)
     return;
 
@@ -1819,7 +1813,6 @@ gtk_text_view_start_cursor_blink (GtkTextView *text_view)
 static void
 gtk_text_view_stop_cursor_blink (GtkTextView *text_view)
 {
-  return;
   if (text_view->blink_timeout == 0)
     return;
 
@@ -2510,6 +2503,11 @@ gtk_text_view_ensure_layout (GtkTextView *text_view)
       if (text_view->buffer)
         gtk_text_layout_set_buffer (text_view->layout, text_view->buffer);
 
+      if ((GTK_WIDGET_HAS_FOCUS (text_view) && text_view->cursor_visible))
+       gtk_text_view_start_cursor_blink (text_view);
+      else
+       gtk_text_layout_set_cursor_visible (text_view->layout, FALSE);
+      
       ltr_context = gtk_widget_create_pango_context (GTK_WIDGET (text_view));
       pango_context_set_base_dir (ltr_context, PANGO_DIRECTION_LTR);
       rtl_context = gtk_widget_create_pango_context (GTK_WIDGET (text_view));
@@ -2544,6 +2542,7 @@ gtk_text_view_destroy_layout (GtkTextView *text_view)
 {
   if (text_view->layout)
     {
+      gtk_text_view_stop_cursor_blink (text_view);
       gtk_text_view_end_selection_drag (text_view, NULL);
       
       gtk_signal_disconnect_by_func (GTK_OBJECT (text_view->layout),